package cn.hxth.dubbo.service.impl;

import cn.hxth.api.model.Product;
import cn.hxth.api.model.ProductBaseInfo;
import cn.hxth.api.query.PageResult;
import cn.hxth.api.query.ProductQueryObject;
import cn.hxth.api.service.IProductService;
import cn.hxth.dubbo.service.mapper.ProductBaseInfoMapper;
import cn.hxth.dubbo.service.mapper.ProductMapper;
import cn.hxth.dubbo.service.mq.RabbitMQSender;
import com.alibaba.fastjson.JSONObject;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Transactional
@Service
public class ProductServiceImpl implements IProductService {
    public ProductServiceImpl() {

    }
    @Resource
    private HttpHeaders headers ;

    @Resource
    private RestTemplate restTemplate ;
    @Resource
    private ProductBaseInfoMapper productBaseInfoMapper ;
    @Resource
    private ProductMapper productMapper ;
    @Resource(name = "myRedisTemplate")
    private RedisTemplate<String,Object> redisTemplate ;
    @Resource
    private RabbitMQSender rabbitMQSender ;
    @Override
    public boolean insertProduct(Product product,ProductBaseInfo productBaseInfo) {
        boolean flag =  this.productMapper.insert(product) ;
        //System.out.println(product.getPid());
        if(flag){
            productBaseInfo.setPid(product.getPid());
           flag = this.productBaseInfoMapper.insert(productBaseInfo) ;
           if(flag)
            this.rabbitMQSender.send("data-change-queue","{\"event_type\": \"add\", \"data_type\": \"product\", \"pid\": " + product.getPid() +   "}");
        }
        return  flag ;
    }

    @Override
    public boolean updateProduct(Product product) {
        boolean flag =  this.productMapper.updateByPrimaryKey(product) ;
        if(flag){
            this.rabbitMQSender.send("data-change-queue","{\"event_type\": \"update\", \"data_type\": \"product\", \"pid\": " + product.getPid() +   "}");
        }
        return  flag ;
    }

    @Override
    public boolean deleteProduct(long pid) {
        Integer sid = this.productMapper.selectSpecByPId(pid) ;
        System.out.println(sid);
        boolean flag =  this.productMapper.deleteByPrimaryKey(pid) ;
        if(flag){

            this.rabbitMQSender.send("data-change-queue","{\"event_type\": \"delete\", \"data_type\": \"product\", \"pid\": " + pid +  ",\"sid\": " + sid + "}");
        }
        return  flag ;
    }


    @Override
    public String getProduct(long pid) {
        JSONObject productBaseInfoJson = null ;
         Product product = null ;



        // String jsonStr = ((String) this.redisTemplate.opsForValue().get("dim_product_" + pid));
             product = this.productMapper.selectByPrimaryKey(pid);
             String productJsonData = JSONObject.toJSONString(product);
             JSONObject productJson = JSONObject.parseObject(productJsonData) ;
             while (true){
                 // 取得对应的商品核心信息（双写一致性去读取）
                 productBaseInfoJson = JSONObject.parseObject( this.restTemplate
                         .exchange("http://localhost:81/pages/product/getProductBaseInfo?pid="+product.getPid(), HttpMethod.GET,
                                 new HttpEntity<Object>(this.headers), String.class)
                         .getBody()) ;
                 if(productBaseInfoJson==null){
                     try {
                         Thread.sleep(10);
                     } catch (InterruptedException e) {
                         e.printStackTrace();
                     }
                     if(productBaseInfoJson!=null)
                         break;
                 }
                 else{
                     break;
                 }
             }
             productJson.put("product_base_info", productBaseInfoJson);
            // this.redisTemplate.opsForValue().set("dim_product_" + pid, productJson.toJSONString());
        System.out.println(productJson);
             return  productJson.toJSONString() ;
         }



    @Override
    public PageResult getProductList(ProductQueryObject productQueryObject) {
        List<Map<String,Object>> infoMaps = new ArrayList<>() ;
        List<Long> pids = this.productMapper.selectPidForCache(productQueryObject) ;
        int count = this.productMapper.selectCount(productQueryObject) ;
        for(long pid :pids){
            String jsonStr = (String) this.redisTemplate.opsForValue().get("product_"+pid);
            Product product = null ;
            if(jsonStr==null) {
                product = this.productMapper.selectByPrimaryKey(pid);
                this.redisTemplate.opsForValue().set("product_"+pid,JSONObject.toJSONString(product));
            }
                else {
                product = JSONObject.parseObject(jsonStr, Product.class);

            }
            System.out.println(product.getPid());
            /*this.restTemplate
                    .exchange("http://localhost:81/pages/product/getProductBaseInfo?pid="+product.getPid(), HttpMethod.GET,
                            new HttpEntity<Object>(this.headers), String.class)
                    .getBody();*/
            // System.out.println(restTemplate.getForObject("http://localhost:81/pages/product/getProductBaseInfo?pid="+product.getPid(), String.class));
                ProductBaseInfo productBaseInfo = JSONObject.parseObject( this.restTemplate
                        .exchange("http://localhost:81/pages/product/getProductBaseInfo?pid="+product.getPid(), HttpMethod.GET,
                                new HttpEntity<Object>(this.headers), String.class)
                        .getBody(),ProductBaseInfo.class) ;
                Map<String,Object> info = new HashMap<>() ;
                info.put("product",product) ;
                info.put("productBaseInfo",productBaseInfo);

                infoMaps.add(info) ;


        }
       /* List<Product> listData = this.productMapper.selectAll(productQueryObject);
        for(Product product:listData){
            ProductBaseInfo productBaseInfo = JSONObject.parseObject(restTemplate.getForObject("http://localhost:81/pages/product/getProductBaseInfo?pid="+product.getPid(), String.class),ProductBaseInfo.class) ;
            Map<String,Object> info = new HashMap<>() ;
            info.put("product",product) ;
            info.put("productBaseInfo",productBaseInfo);
            infoMaps.add(info) ;
        }*/
        return new PageResult(infoMaps,count,productQueryObject.getCurrentPage(),productQueryObject.getPageSize()) ;

    }
    public Product getProductForUpdate(long pid) {
        Product product = null ;


            product = this.productMapper.selectByPrimaryKey(pid);

            return  product ;


    }

    @Override

    public Long getPidBySid(int sid) {
        Object object = this.redisTemplate.opsForValue().get(sid + "-product");
        if(object!=null){
            return  Long.parseLong(object.toString()) ;
        }
        Long pid = this.productMapper.selectBySpecId(sid);
        if (pid!=null)
        this.redisTemplate.opsForValue().set(sid + "-product",String.valueOf(pid));
       return pid  ;
    }
}
